<!DOCTYPE html>
<html>
<head>
  <title>Mono sanity check</title>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>
<body>
  <p>Simple sanity check to ensure the Mono runtime works in basic cases.</p>

  <fieldset>
    <legend>Add numbers</legend>
    <form id="addNumbers">
      <input id="addNumberA" value="123" /> +
      <input id="addNumberB" value="456" /> =
      <input id="addNumbersResult" readonly />
      <button type="submit" disabled>Go</button>
    </form>
  </fieldset>

  <fieldset>
    <legend>Repeat string</legend>
    <form id="repeatString">
      <input id="repeatStringStr" value="Hello" /> *
      <input id="repeatStringCount" value="3" type="number" /> =
      <input id="repeatStringResult" readonly />
      <button type="submit" disabled>Go</button>
    </form>
  </fieldset>

  <fieldset>
    <legend>Trigger .NET exception</legend>
    <form id="triggerException">
      <input id="triggerExceptionMessage" value="Your message here" />
      <button type="submit" disabled>Go</button>
      <div><textarea rows="5" cols="80" readonly id="triggerExceptionMessageStackTrace"></textarea></div>
    </form>
  </fieldset>

  <fieldset>
    <legend>Call JS from .NET</legend>
    <form id="callJs">
      <input id="callJsEvalExpression" value="location.href" />
      <button type="submit" disabled>Go</button>
      <div><textarea rows="5" cols="80" readonly id="callJsResult"></textarea></div>
    </form>
  </fieldset>

  <fieldset>
    <legend>Call JS from .NET (no boxing)</legend>
    <form id="callJsNoBoxing">
      <input id="callJsNoBoxingNumberA" value="28" /> /
      <input id="callJsNoBoxingNumberB" value="4" /> =
      <input id="callJsNoBoxingResult" readonly />
      <button type="submit" disabled>Go</button>
    </form>
  </fieldset>

  <fieldset>
    <legend>Get runtime OS</legend>
    <form id="getRuntimeInformation">
      <button type="submit" disabled>Get</button>
      <input id="getRuntimeInformationResult" readonly />
    </form>
  </fieldset>

  <p id="loadingIndicator">Loading...</p>

  <script src="loader.js"></script>
  <script>
    initMono(['MonoSanityClient.dll', 'MonoSanityClient.pdb'], function () {
      var buttons = document.getElementsByTagName('button');
      for (var i = 0; i < buttons.length; i++) {
        buttons[i].disabled = false;
      }
      el('loadingIndicator').style.display = 'none';
      window.isTestReady = true; // The Xunit code polls until this is true
    });

    el('addNumbers').onsubmit = function (evt) {
      evt.preventDefault();
      var a = parseInt(el('addNumberA').value);
      var b = parseInt(el('addNumberB').value);
      var result = invokeMonoMethod('MonoSanityClient', 'MonoSanityClient', 'Examples', 'AddNumbers', [a, b]);
      el('addNumbersResult').value = result;
    };

    el('repeatString').onsubmit = function (evt) {
      evt.preventDefault();
      var str = el('repeatStringStr').value;
      var count = parseInt(el('repeatStringCount').value);
      var result = invokeMonoMethod('MonoSanityClient', 'MonoSanityClient', 'Examples', 'RepeatString', [str, count]);
      el('repeatStringResult').value = result;
    };

    el('triggerException').onsubmit = function (evt) {
      evt.preventDefault();
      var message = el('triggerExceptionMessage').value;
      try {
        invokeMonoMethod('MonoSanityClient', 'MonoSanityClient', 'Examples', 'TriggerException', [message]);
        el('triggerExceptionMessageStackTrace').value = 'WARNING: No exception occurred';
      } catch (ex) {
        el('triggerExceptionMessageStackTrace').value = ex.toString();
      }
    };

    el('callJs').onsubmit = function (evt) {
      evt.preventDefault();
      var expression = el('callJsEvalExpression').value;
      var result = invokeMonoMethod('MonoSanityClient', 'MonoSanityClient', 'Examples', 'EvaluateJavaScript', [expression]);
      el('callJsResult').value = result;
    };

    el('callJsNoBoxing').onsubmit = function (evt) {
      evt.preventDefault();
      var a = parseInt(el('callJsNoBoxingNumberA').value);
      var b = parseInt(el('callJsNoBoxingNumberB').value);
      var result = invokeMonoMethod('MonoSanityClient', 'MonoSanityClient', 'Examples', 'CallJsNoBoxing', [a, b]);
      el('callJsNoBoxingResult').value = result;
    };

    el('getRuntimeInformation').onsubmit = function (evt) {
      evt.preventDefault();
      var result = invokeMonoMethod('MonoSanityClient', 'MonoSanityClient', 'Examples', 'GetRuntimeInformation', []);
      el('getRuntimeInformationResult').value = result;
    };

    function el(id) {
      return document.getElementById(id);
    }

    // Examples of functions we can invoke from .NET

    function getUserAgentString() {
      return navigator.userAgent;
    }

    function triggerJsException() {
      throw new Error('This is a JavaScript exception.');
    }

    function evaluateJsExpression(dotNetStringExpression) {
      var result = eval(dotnetStringToJavaScriptString(dotNetStringExpression));
      return result === null || result === undefined
        ? result // Pass through null/undefined so we can verify this is handled upstream
        : javaScriptStringToDotNetString(result.toString());
    }

    function divideNumbersUnmarshalled(a, b) {
      // In this example, neither the arguments nor return value are boxed
      // -- we expect to receive and return numbers directly
      if (b === 0) {
        throw new Error('Division by zero');
      }
      return a / b;
    }
  </script>
</body>
</html>
